<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //声明函数：函数调用、参数、返回值
        //函数表达式：将函数赋值给一个变量，用变量名进行调用
        let fn = function add(a,b){
            return a+b;
        }
        console.log(fn(1,2));
        //立即执行函数：匿名函数自调用
        (function(){
            console.log('立即执行函数')
        })();
        //回调：把函数当作另一个函数的参数传入，在另一个函数中调用它
        //递归：把函数当作自己函数本身的参数，在函数自身调用自己
        //递归执行时容易造成死循环
        //把函数当作返回值  >闭包
        let fn1 = function(a,b){
            return a+b;
        }

        let fn2 = function(f){
            return f;
        }
        console.log(fn2(10));
        console.log(fn2(fn1(1,2)));
        //作用域：变量作用的范围
        //js代码运行的两个阶段
        /*1.解析（编译）：语法检查、声明变量和函数
        2.运行：变量赋值、按执行流程执行代码
        var和let的区别
        1.var可以重复声明变量，let不允许
        2.var允许变量声明提升，let没有（暂时性的死区）>var允许先访问后声明
        ，二let访问前必须声明变量
      3.let和const比var使用更严谨
        */
      
       console.log(t1);
       console.log(t2);
       var t1=123;
       let t2=456;
      //3.var和let都有全局作用域、函数作用域，对于let多了一个块作用域
      //全局变量
      let num1=10;
      var num2=20;
      function fun(){
        //局部变量：函数作用域中声明的变量
        let f1='hello';
        var f2='js';
        console.log(num1);
        console.log(num2);
        console.log(f1);//let：局部变量在超出作用范围后不能访问，会报错
        console.log(f2);//var：局部变量在超出作用范围后不能访问，会报错
     }
    fun();
    console.log('块作用域-------------------')
        //块作用域{}
     for(let i=0;i<3;i++){
        console.log('let:'+i)
     }
     //console.log('i'+i);//块作用域外无法访问其变量
     for(var j=0;j<3;j++){
        console.log('var:'+j)
     }
    </script>
</body>
</html>